import {
    EventBus
} from '@/utils/EventBus'
import * as THREE from 'three'
import {
    BaseModel
} from './BaseModel'
export class Ship extends BaseModel {

    init () {
        this.scene.add(this.model)
        this.pointIndex = 0 // 保存当前游船所在位置坐标的索引
        this.generatorMovePath() // 生成游船移动的路径
        this.isMoveCamera = false // 开关属性（控制摄像机是否跟随游船移动）
        this.isMouseTouching = false // 判断漫游时鼠标是否被按下去
        this.prePos = 0 // 保存鼠标按下时的x坐标
        this.onModelAttach() // 鼠标事件
    }

    // 生成游船行进的坐标点集合
    generatorMovePath () {
        // 设置平滑的三维样条曲线路线坐标点，CatmullRomCurve3
        // 设置关键的几个点坐标，其他的构造函数内会帮我们计算
        const shipPath = new THREE.CatmullRomCurve3([
            new THREE.Vector3(134.356097129589, 2.0112688541412354, -78.91746888546072),
            new THREE.Vector3(13.132075955743915, 2.0112688541412425, -69.85260460470285),
            new THREE.Vector3(13.132075955743915, 2.0112688541412425, -69.85260460470285),
            new THREE.Vector3(-80.28995611104816, 2.0112688541412282, -12.640254617216172),
            new THREE.Vector3(-71.5470123066941, 2.0112688541412354, 25.641138454485144),
            new THREE.Vector3(-71.5470123066941, 2.0112688541412354, 25.641138454485144),
            new THREE.Vector3(-17.5179164111899, 2.0112688541412354, 139.95062075065943),
            new THREE.Vector3(-67.10547001341894, 2.0112688541412354, 64.30494908329582),
            new THREE.Vector3(-87.03568940230136, 2.0112688541412354, 20.40776369519459),
            new THREE.Vector3(-88.0509634357777, 2.0112688541412425, -32.429601593890354),
            new THREE.Vector3(-70.27457116256328, 2.0112688541412425, -50.370253013515836),
            new THREE.Vector3(-39.206573479212764, 2.0112688541412425, -64.28841112963838),
            new THREE.Vector3(47.33347662423566, 2.0112688541412354, -73.13885409538068),
            new THREE.Vector3(134.356097129589, 2.0112688541412354, -78.91746888546072),
        ])
        // getSpacedPoints 等间距的坐标点
        this.pointArr = shipPath.getSpacedPoints(3500)

        // 显示坐标点 => 几何图形 => 线段物体
        const geometry = new THREE.BufferGeometry().setFromPoints(this.pointArr)
        const material = new THREE.LineBasicMaterial({
            color: 0x00ff00,
            side: THREE.DoubleSide
        })
        const line = new THREE.Line(geometry, material)
        this.scene.add(line)
    }

    // ship类新增旋转相机的方法
    onModelAttach () {
        EventBus.getInstance().on('mode-roaming',  (isOpen) => {
           if (isOpen) {
                console.log(this, 'this');
                window.addEventListener('mousedown', this.onMouseDownFn)
                window.addEventListener('mousemove', this.onMouseMoveFn)
                window.addEventListener('mouseup', this.onMouseUpFn)
           } else {
                window.removeEventListener('mousedown', this.onMouseDownFn)
                window.removeEventListener('mousemove', this.onMouseMoveFn)
                window.removeEventListener('mouseup', this.onMouseUpFn)
           }
        })
    }

    onMouseDownFn = (e) => {
        this.isMouseTouching = true
    }

    onMouseMoveFn =  (e) => {
        if (this.isMouseTouching) {
            // 注意这里的this指向问题，得使用箭头函数，拿到的this才是ship实例
            // 往右滑，其实是向左转，所以应该是上一个值减去e.clientX, 乘以0.01是因为是弧度制
            this.camera.rotateY((this.prePos - e.clientX) * 0.01)
        }

        this.prePos = e.clientX
    }

    onMouseUpFn = (e) => {
        this.isMouseTouching = false
        this.prePos = 0
    }
    

    // 该方法，每秒60个周期每帧
    onTick () {
        if (this.pointIndex < this.pointArr.length - 1) {
            const {
                x, y, z
            } = this.pointArr[this.pointIndex + 1]
            if (this.isMoveCamera) { // 移动摄像机
                if (!this.isMouseTouching) { // 鼠标没有被按下，设置摄像机的lookAt
                    // 先设置摄像机的朝向，再设置摄像机的位置：就像跑步的过程中你碰到了十字路口，要先选择某个方向准备转弯，然后才会到达新的地点，所有是先设置方向，再设置位置
                    this.camera.lookAt(x, y + 20, z)
                }
                this.camera.position.set(x, y + 20, z)
            }
            // 取出坐标给游船移动
            this.model.position.copy(this.pointArr[this.pointIndex])
            // 确保船头朝向下一个坐标点方向
            this.model.lookAt(this.pointArr[this.pointIndex + 1])
            this.pointIndex++
        } else {
            // 重新记录坐标的值然后做动画效果
            this.pointIndex = 0
        }
    }
}
